package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.NoteFormDTO;
import com.tianji.learning.domain.po.LearningNote;
import com.tianji.learning.domain.query.NotePageQuery;
import com.tianji.learning.domain.vo.NoteVO;
import com.tianji.learning.mapper.LearningNoteMapper;
import com.tianji.learning.service.ILearningNoteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 学习笔记表 服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2025-11-08
 */
@Service
@RequiredArgsConstructor
public class LearningNoteServiceImpl extends ServiceImpl<LearningNoteMapper, LearningNote> implements ILearningNoteService {

    private final UserClient userClient;

    @Override
    public void saveNote(NoteFormDTO noteDTO) {
        // 创建笔记实体
        LearningNote note = new LearningNote();
        note.setUserId(UserContext.getUser());
        note.setCourseId(noteDTO.getCourseId());
        note.setChapterId(noteDTO.getChapterId());
        note.setSectionId(noteDTO.getSectionId());
        note.setNoteMoment(noteDTO.getNoteMoment());
        note.setContent(noteDTO.getContent());
        note.setIsPrivate(noteDTO.getIsPrivate());

        // 保存笔记
        this.save(note);
    }

    @Override
    public PageDTO<NoteVO> queryAllNotePage(NotePageQuery query) {
        Long courseId = query.getCourseId();
        Long sectionId = query.getSectionId();
        if (courseId == null && sectionId == null) {
            throw new BadRequestException("课程id和小节id不能都为空");
        }
        
        // 检查onlyMine为true时用户是否登录
        if (Boolean.TRUE.equals(query.getOnlyMine()) && UserContext.getUser() == null) {
            throw new BadRequestException("查询自己的笔记需要先登录");
        }

        // 1.分页查询
        Page<LearningNote> page = lambdaQuery()
                .select(LearningNote.class, info -> !info.getProperty().equals("description"))
                .eq(Boolean.TRUE.equals(query.getOnlyMine()), LearningNote::getUserId, UserContext.getUser())
                .eq(courseId != null, LearningNote::getCourseId, courseId)
                .eq(sectionId != null, LearningNote::getSectionId, sectionId)
                .eq(Boolean.FALSE.equals(query.getOnlyMine()), LearningNote::getIsPrivate, false) // 只有在查询公开笔记时才过滤私密笔记
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<LearningNote> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }

        // 2.查询用户信息
        Set<Long> userIds = records.stream().map(LearningNote::getUserId).collect(Collectors.toSet());
        List<UserDTO> users = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = new HashMap<>();
        if (CollUtils.isNotEmpty(users)) {
            userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        }

        // 3.封装VO
        Map<Long, UserDTO> finalUserMap = userMap;
        List<NoteVO> voList = records.stream().map(record -> {
            NoteVO vo = new NoteVO();
            vo.setId(record.getId());
            vo.setContent(record.getContent());
            vo.setNoteMoment(record.getNoteMoment());
            vo.setIsPrivate(record.getIsPrivate());
            vo.setIsGathered(false); // TODO 后续实现采集功能时再更新该字段
            vo.setUserId(record.getUserId());
            
            UserDTO user = finalUserMap.get(record.getUserId());
            if (user != null) {
                vo.setUserName(user.getName());
                vo.setUserIcon(user.getIcon());
            }
            
            vo.setCreateTime(record.getCreateTime());
            return vo;
        }).collect(Collectors.toList());

        return PageDTO.of(page, voList);
    }
}